import os
import logging
import time
import glob
import json
import requests
import uuid
from datetime import datetime
from typing import List, Dict, Optional
from dataclasses import dataclass
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.select import Select
from sqlalchemy import update
from app.db.models import TPost
from app.db.database import SessionLocal
import traceback
from selenium.common.exceptions import TimeoutException, NoSuchElementException

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('tts_automation_dialogue.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

@dataclass
class DialogueLine:
    id: str  # 台词编号
    role: str  # 角色名称
    voice: str  # 语音选项
    emotion: str  # 感情选项
    intensity: str  # 强度选项
    content: str  # 台词内容

class TTSDialogueAutomation:
    def __init__(self, base_dir: str = "/app/downloads", username: str = "zxsr20", password: str = "aA@#$67028"):
        self.base_dir = base_dir
        self.username = username
        self.password = password
        self.driver = None
        self.is_logged_in = False
        self.cookie_file = os.path.join(base_dir, "tts_cookies.json")
        self.selenium_hub_url = 'http://selenium-hub:4444'
        self.is_close_popup = False
        
        # 创建基础下载目录
        os.makedirs(self.base_dir, exist_ok=True)
        
        # 创建今天的日期目录
        self.today_dir = os.path.join(self.base_dir, datetime.now().strftime('%Y%m%d'))
        os.makedirs(self.today_dir, exist_ok=True)

    def _cleanup_selenium_sessions(self):
        """清理所有活跃的Selenium会话"""
        try:
            response = requests.get(f"{self.selenium_hub_url}/wd/hub/sessions")
            if response.status_code == 200:
                sessions = response.json().get('value', [])
                for session in sessions:
                    session_id = session.get('id')
                    if session_id:
                        try:
                            delete_url = f"{self.selenium_hub_url}/wd/hub/session/{session_id}"
                            requests.delete(delete_url)
                            logger.info(f"Cleaned up session: {session_id}")
                        except Exception as e:
                            logger.error(f"Error cleaning up session {session_id}: {str(e)}")
        except Exception as e:
            #打印错误堆栈到日志
            logger.error(f"Error getting Selenium sessions: {str(e)}")
            traceback.print_exc()
            logger.error(f"Error getting Selenium sessions: {str(e)}")
    def _setup_driver(self):
        """设置并初始化WebDriver"""
        try:
            self._cleanup_selenium_sessions()
            
            if self.driver:
                try:
                    self.driver.quit()
                except:
                    pass
                self.driver = None
            
            chrome_options = Options()
            chrome_options.add_argument('--no-sandbox')
            chrome_options.add_argument('--disable-dev-shm-usage')
            chrome_options.add_argument('--headless')
            chrome_options.add_argument('--disable-gpu')
            
            prefs = {
                "download.default_directory": "/home/seluser/Downloads",
                "download.prompt_for_download": False,
                "download.directory_upgrade": True,
                "safebrowsing.enabled": True,
                "download.default_directory_infobar_shown": False
            }
            chrome_options.add_experimental_option("prefs", prefs)
            chrome_options.set_capability("platformName", "linux")
            
            logger.info("Connecting to Selenium Grid")
            self.driver = webdriver.Remote(
                command_executor=f'{self.selenium_hub_url}/wd/hub',
                options=chrome_options
            )
            logger.info("Successfully connected to Selenium Grid")
        except Exception as e:
            logger.error(f"Error setting up WebDriver: {str(e)}")
            raise

    def _save_cookies(self):
        """保存cookies到文件"""
        if self.driver:
            cookies = self.driver.get_cookies()
            with open(self.cookie_file, 'w') as f:
                json.dump(cookies, f)
            logger.info("Cookies saved successfully")

    def _load_cookies(self) -> bool:
        """从文件加载cookies"""
        try:
            if os.path.exists(self.cookie_file):
                with open(self.cookie_file, 'r') as f:
                    cookies = json.load(f)
                for cookie in cookies:
                    try:
                        self.driver.add_cookie(cookie)
                    except Exception as e:
                        logger.error(f"Error adding cookie: {str(e)}")
                logger.info("Cookies loaded successfully")
                return True
            return False
        except Exception as e:
            logger.error(f"Error loading cookies: {str(e)}")
            return False

    def _login(self) -> bool:
        """执行登录操作"""
        try:
            logger.info("Starting login process")
            self.driver.get("http://new.text-to-speech.cn/tts/")
            
            if self._load_cookies():
                self.driver.refresh()
                try:
                    WebDriverWait(self.driver, 5).until(
                        EC.presence_of_element_located((By.CSS_SELECTOR, "textarea.form-control"))
                    )
                    # 等待生成按钮出现
                    WebDriverWait(self.driver, 5).until(
                        EC.presence_of_element_located((By.CSS_SELECTOR, "button#btnUpdate"))
                    )
                    logger.info("Already logged in via cookies")
                    self.is_logged_in = True
                    return True
                except:
                    logger.info("Cookies expired or invalid, proceeding with manual login")
                    self.is_logged_in = False
                    #删除cookies文件
                    if os.path.exists(self.cookie_file):
                        os.remove(self.cookie_file)
            
            nav_login_button = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, "a.login-btn.navbar-button"))
            )
            nav_login_button.click()
            
            username_input = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "input[placeholder='请输入电子邮箱/用户名']"))
            )
            username_input.send_keys(self.username)
            
            password_input = self.driver.find_element(By.CSS_SELECTOR, "input[placeholder='请输入密码']")
            password_input.send_keys(self.password)
            
            login_button = self.driver.find_element(By.CSS_SELECTOR, "button.go-login")
            self.driver.execute_script("arguments[0].click();", login_button)
            
            time.sleep(3)
            self.is_logged_in = True
            
            self._save_cookies()
            
            logger.info("Login successful")
            return True
            
        except Exception as e:
            logger.error(f"Login failed: {str(e)}")
            return False

    def _select_voice_options(self, dialogue: DialogueLine) -> bool:
        """选择语音、感情和强度选项"""
        try:
            logger.info(f"开始为台词 {dialogue.id} 选择语音选项")
            logger.info(f"尝试选择语音: {dialogue.voice}")
            
            # 选择语音
            voice_select = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "select#voice"))
            )
            logger.info("找到语音选择框")
            
            # 获取所有可用的语音选项及其value值
            voice_options = [(option.get_attribute('value'), option.text) for option in voice_select.find_elements(By.TAG_NAME, "option")]
            logger.info(f"可用的语音选项: {voice_options}")
            
            # 从括号中提取语音名称进行匹配
            voice_name = dialogue.voice.split('(')[0].strip()  # 例如从 "云健(成年男)" 提取 "云健"
            matching_voice = None
            matching_value = None
            
            # 先尝试通过文本匹配
            for value, text in voice_options:
                if voice_name in text:
                    matching_voice = text
                    matching_value = value
                    break
            
            if matching_value:
                logger.info(f"找到匹配的语音选项: {matching_voice} (value: {matching_value})")
                # 优先使用value值选择
                Select(voice_select).select_by_value(matching_value)
                logger.info(f"已选择语音: {matching_voice}")
            else:
                logger.error(f"未找到匹配的语音选项: {voice_name}")
                logger.error(f"可用选项: {voice_options}")
                return False
                
            # 增加等待时间，确保感情选项加载完成
            time.sleep(2)  # 等待选项加载

            logger.info(f"尝试选择感情: {dialogue.emotion}")
            # 选择感情
            emotion_select = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "select#style"))
            )
            logger.info("找到感情选择框")
            
            # 获取所有可用的感情选项（排除"请选择感情"）
            emotion_options = [(option.get_attribute('value'), option.text) 
                             for option in emotion_select.find_elements(By.TAG_NAME, "option")
                             if option.get_attribute('value') != '0']
            
            logger.info(f"可用的感情选项: {emotion_options}")
            
            # 如果指定的感情选项存在就使用，否则选择第一个可用选项
            try:
                emotion_values = [value for value, _ in emotion_options]
                if emotion_options:  # 确保有可用选项
                    if dialogue.emotion in emotion_values:
                        Select(emotion_select).select_by_value(dialogue.emotion)
                        logger.info(f"已选择指定感情: {dialogue.emotion}")
                    else:
                        first_value = emotion_options[0][0]
                        Select(emotion_select).select_by_value(first_value)
                        logger.info(f"指定感情 {dialogue.emotion} 不可用，已选择第一个可用选项: {first_value}")
                else:
                    logger.error("没有可用的感情选项")
                    return False
            except Exception as e:
                logger.error(f"选择感情选项失败: {str(e)}")
                logger.error(f"可用选项: {emotion_options}")
                return False

            logger.info(f"尝试选择强度: {dialogue.intensity}")
            # 选择强度
            intensity_select = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "select#styledegree"))
            )
            logger.info("找到强度选择框")
            
            # 获取所有可用的强度选项（排除"请选择强度"）
            intensity_options = [(option.get_attribute('value'), option.text) 
                               for option in intensity_select.find_elements(By.TAG_NAME, "option")
                               if option.get_attribute('value') != '0']
            
            logger.info(f"可用的强度选项: {intensity_options}")
            
            # 如果指定的强度选项存在就使用，否则选择第一个可用选项
            try:
                intensity_values = [value for value, _ in intensity_options]
                if intensity_options:  # 确保有可用选项
                    if dialogue.intensity in intensity_values:
                        Select(intensity_select).select_by_value(dialogue.intensity)
                        logger.info(f"已选择指定强度: {dialogue.intensity}")
                    else:
                        first_value = intensity_options[0][0]
                        Select(intensity_select).select_by_value(first_value)
                        logger.info(f"指定强度 {dialogue.intensity} 不可用，已选择第一个可用选项: {first_value}")
                else:
                    logger.error("没有可用的强度选项")
                    return False
            except Exception as e:
                logger.error(f"选择强度选项失败: {str(e)}")
                logger.error(f"可用选项: {intensity_options}")
                return False
            
            return True
            
        except Exception as e:
            logger.error(f"选择选项时出错: {str(e)}")
            logger.error(f"当前页面源码: {self.driver.page_source}")
            return False

    def _wait_for_download(self, timeout: int = 30) -> Optional[str]:
        """等待文件下载完成并返回文件路径"""
        start_time = time.time()
        while time.time() - start_time < timeout:
            try:
                files = [f for f in glob.glob(os.path.join(self.base_dir, '*')) 
                        if os.path.isfile(f) and not f.endswith('.crdownload') 
                        and not f.endswith('.tmp') 
                        and not f.endswith('tts_cookies.json')]
                
                if files:
                    latest_file = max(files, key=os.path.getmtime)
                    logger.info(f"Found file: {latest_file}")
                    
                    if os.path.getsize(latest_file) > 0 and latest_file.endswith('.mp3'):
                        return latest_file
                    else:
                        logger.error(f"Invalid file: {latest_file} (size: {os.path.getsize(latest_file)})")
                else:
                    logger.info("No valid files found in download directory yet...")
            except Exception as e:
                logger.error(f"Error while checking download directory: {str(e)}")
            
            time.sleep(1)
            
        logger.error(f"Download timeout after {timeout} seconds")
        return None

    def _handle_popup(self):
        """处理页面上的弹窗"""
        try:
            if self.is_close_popup:
                logger.info("已关闭弹窗，跳过处理")
                return True
            logger.info("等待弹窗出现")
            # 等待弹窗出现
            popup = WebDriverWait(self.driver, 5).until(
                EC.presence_of_element_located((By.CLASS_NAME, "swal2-popup"))
            )
            logger.info(f"弹窗是否显示: {popup.is_displayed()}")
            
            if popup.is_displayed():
                # 首先尝试查找并点击关闭按钮（×）
                try:
                    close_button = WebDriverWait(self.driver, 3).until(
                        EC.element_to_be_clickable((By.CLASS_NAME, "swal2-close"))
                    )
                    logger.info("找到关闭按钮，点击关闭")
                    self.driver.execute_script("arguments[0].click();", close_button)
                    self.is_close_popup = True
                    time.sleep(1)  # 等待弹窗消失
                    return True
                except:
                    logger.info("未找到关闭按钮，尝试确认按钮")
                
                # 如果没有关闭按钮，尝试确认按钮
                try:
                    confirm_button = WebDriverWait(self.driver, 3).until(
                        EC.element_to_be_clickable((By.CLASS_NAME, "swal2-confirm"))
                    )
                    logger.info("找到确认按钮，点击确认")
                    self.driver.execute_script("arguments[0].click();", confirm_button)
                    self.is_close_popup = True
                    time.sleep(1)  # 等待弹窗消失
                    return True
                except:
                    logger.warning("未找到确认按钮")
                
                # 如果都没有找到，尝试直接通过JavaScript关闭弹窗
                try:
                    logger.info("尝试通过JavaScript关闭弹窗")
                    self.driver.execute_script("""
                        var elements = document.getElementsByClassName('swal2-container');
                        for(var i=0; i<elements.length; i++) {
                            elements[i].remove();
                        }
                    """)
                    self.is_close_popup = True
                    time.sleep(1)
                    return True
                except:
                    logger.warning("JavaScript关闭弹窗失败")
                
                return False
                
        except TimeoutException:
            # 没有找到弹窗，说明可能没有弹窗
            return False
        except Exception as e:
            logger.warning(f"处理弹窗时出现异常: {str(e)}")
            return False
        return False

    def _process_single_dialogue(self, dialogue: DialogueLine) -> Optional[str]:
        """处理单个台词的转换"""
        try:
            logger.info(f"开始处理台词 {dialogue.id}")
            logger.info(f"台词内容: {dialogue.content}")
            logger.info(f"角色: {dialogue.role}")

            # 处理可能存在的弹窗
            self._handle_popup()
            
            # 检查台词内容是否为空
            if not dialogue.content or len(dialogue.content.strip()) == 0:
                logger.info(f"跳过台词 {dialogue.id} (内容为空)")
                return None
                
            # 等待文本框加载并输入文本
            logger.info("等待文本框加载")
            text_area = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "textarea.form-control"))
            )
            logger.info("文本框已加载，清除现有内容")
            text_area.clear()
            logger.info("输入新内容")
            text_area.send_keys(dialogue.content)
            logger.info("内容输入完成")
            
            # 选择语音选项
            logger.info("开始选择语音选项")
            if not self._select_voice_options(dialogue):
                raise Exception("选择语音选项失败")
            
            # 再次处理可能出现的弹窗
            self._handle_popup()
            
            # 点击生成按钮前确保没有遮挡
            logger.info("等待生成按钮加载")
            
            # 尝试多次查找和点击生成按钮
            max_attempts = 3
            for attempt in range(max_attempts):
                try:
                    # 处理可能存在的弹窗
                    self._handle_popup()
                    
                    # 等待按钮可见和可点击
                    generate_button = WebDriverWait(self.driver, 10).until(
                        EC.element_to_be_clickable((By.CSS_SELECTOR, "button#btnUpdate"))
                    )
                    
                    # 确保按钮在视图中
                    self.driver.execute_script("arguments[0].scrollIntoView(true);", generate_button)
                    time.sleep(1)  # 等待滚动完成
                    
                    logger.info("点击生成按钮")
                    self.driver.execute_script("arguments[0].click();", generate_button)
                    logger.info("已点击生成按钮")
                    break
                except TimeoutException:
                    # 打印当前页面源码和状态
                    logger.warning(f"第 {attempt + 1} 次尝试点击生成按钮失败，当前页面状态：")
                    try:
                        # 尝试直接找到按钮（不等待）看看是否存在
                        button = self.driver.find_element(By.CSS_SELECTOR, "button#btnUpdate")
                        logger.warning(f"按钮存在但不可点击，按钮HTML: {button.get_attribute('outerHTML')}")
                        logger.warning(f"按钮是否显示: {button.is_displayed()}")
                        logger.warning(f"按钮是否启用: {button.is_enabled()}")
                    except:
                        logger.warning("按钮完全不存在于页面中")
                        # 打印当前页面中所有按钮元素
                        logger.warning("当前页面所有按钮元素：")
                        all_buttons = self.driver.find_elements(By.TAG_NAME, "button")
                        for btn in all_buttons:
                            logger.warning(f"按钮HTML: {btn.get_attribute('outerHTML')}")
                        
                        # 打印包含特定区域的HTML
                        logger.warning("页面主要内容区域：")
                        try:
                            main_content = self.driver.find_element(By.ID, "main-content")
                            logger.warning(f"主内容区域HTML: {main_content.get_attribute('innerHTML')}")
                        except:
                            logger.warning("无法找到主内容区域，打印整个页面HTML：")
                            logger.warning(self.driver.page_source)
                    
                    if attempt == max_attempts - 1:
                        raise Exception("无法点击生成按钮")
                    logger.warning(f"重试中...")
                    time.sleep(2)
            
            # 等待生成完成并下载
            try:
                logger.info("等待下载按钮出现")
                download_button = None
                download_selectors = [
                    "//button[contains(text(), '下载')]",
                    "//button[contains(@class, 'download')]",
                    "//button[contains(@class, 'btn-success')]",
                    "//a[contains(text(), '下载')]"
                ]
                
                for selector in download_selectors:
                    try:
                        logger.info(f"尝试查找下载按钮，使用选择器: {selector}")
                        download_button = WebDriverWait(self.driver, 60).until(
                            EC.element_to_be_clickable((By.XPATH, selector))
                        )
                        if download_button:
                            logger.info(f"找到下载按钮，使用选择器: {selector}")
                            break
                    except:
                        logger.warning(f"使用选择器 {selector} 未找到下载按钮")
                        continue
                
                if not download_button:
                    logger.error("未找到可用的下载按钮")
                    raise Exception("下载按钮未找到或不可点击")
                
                logger.info("点击下载按钮")
                self.driver.execute_script("arguments[0].click();", download_button)
                logger.info("已点击下载按钮")
                
            except Exception as e:
                logger.error(f"等待生成完成时出错: {str(e)}")
                try:
                    logger.error(f"当前页面源码: {self.driver.page_source}")
                except:
                    logger.error("无法获取页面源码")
                raise Exception("TTS生成超时或失败")
            
            # 等待下载完成
            logger.info("等待文件下载")
            downloaded_file = self._wait_for_download()
            if not downloaded_file:
                logger.error("文件下载失败或超时")
                raise Exception("下载失败或超时")
            
            logger.info(f"文件下载完成: {downloaded_file}")
            
            # 使用台词ID作为文件名
            new_filename = f"{dialogue.id}.mp3"
            new_filepath = os.path.join(self.today_dir, new_filename)
            logger.info(f"准备将文件重命名为: {new_filepath}")
            
            # 如果目标文件已存在，先删除
            if os.path.exists(new_filepath):
                logger.info(f"删除已存在的文件: {new_filepath}")
                os.remove(new_filepath)
            
            logger.info(f"重命名文件 {downloaded_file} -> {new_filepath}")
            os.rename(downloaded_file, new_filepath)
            
            # 验证文件是否成功重命名
            if os.path.exists(new_filepath):
                logger.info(f"台词 {dialogue.id} 处理成功")
                return new_filepath
            else:
                logger.error(f"重命名文件失败: {new_filepath}")
                raise Exception(f"重命名文件失败: {new_filepath}")
            
        except TimeoutException as e:
            logger.error(f"元素等待超时: {e.msg}")  # 访问异常对象的 msg 属性
            logger.error(f"处理台词出错，完整错误:\n{traceback.format_exc()}")
        except NoSuchElementException as e:
            logger.error(f"元素不存在: {e}")
        except Exception as e:
            logger.error(f"处理台词出错，完整错误:\n{traceback.format_exc()}")
            logger.error(f"处理台词 {dialogue.id} 时出错: {str(e)}")
            logger.error(f"当前下载目录内容: {os.listdir(self.base_dir)}")
            return None

    def _get_voice_emotion_mappings(self) -> dict:
        """获取所有语音及其对应的感情选项映射"""
        try:
            logger.info("开始获取语音和感情选项映射关系")
            
            # 获取语音选择框
            voice_select = WebDriverWait(self.driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "select#voice"))
            )
            
            # 获取所有语音选项
            voice_options = [(option.get_attribute('value'), option.text) 
                           for option in voice_select.find_elements(By.TAG_NAME, "option")
                           if option.get_attribute('value') != '0']  # 排除"请选择语音"选项
            
            logger.info(f"找到 {len(voice_options)} 个语音选项")
            
            # 存储结果的字典
            voice_emotion_map = {}
            
            # 遍历每个语音选项
            for voice_value, voice_text in voice_options:
                logger.info(f"\n正在获取语音 {voice_text} 的感情选项")
                
                # 选择语音
                Select(voice_select).select_by_value(voice_value)
                time.sleep(3)  # 等待感情选项加载
                
                # 获取感情选择框
                emotion_select = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "select#style"))
                )
                
                # 等待感情选项加载完成
                max_retries = 10
                retry_count = 0
                last_options_count = 0
                
                while retry_count < max_retries:
                    emotion_options = [(option.get_attribute('value'), option.text) 
                                     for option in emotion_select.find_elements(By.TAG_NAME, "option")
                                     if option.get_attribute('value') != '0']  # 排除"请选择感情"选项
                    current_count = len(emotion_options)
                    
                    if current_count > 0 and current_count == last_options_count:
                        break
                        
                    last_options_count = current_count
                    time.sleep(1)
                    retry_count += 1
                
                # 存储结果
                voice_emotion_map[voice_text] = emotion_options
                logger.info(f"语音 {voice_text} 有 {len(emotion_options)} 个感情选项")
                for emotion_value, emotion_text in emotion_options:
                    logger.info(f"  - {emotion_value}: {emotion_text}")
            
            # 打印映射关系
            print("\n=== 语音与感情选项对应关系 ===")
            for voice, emotions in voice_emotion_map.items():
                print(f"\n语音: {voice}")
                print("可用感情选项:")
                for emotion_value, emotion_text in emotions:
                    print(f"  - {emotion_value}: {emotion_text}")
                print("-" * 50)
            
            return voice_emotion_map
            
        except Exception as e:
            logger.error(f"获取语音感情选项映射时出错: {str(e)}")
            return {}

    def process_dialogues(self, dialogues: List[DialogueLine]) -> Dict[str, str]:
        """批量处理台词列表"""
        results = {}
        
        try:
            # 过滤掉空内容的台词
            valid_dialogues = [dialogue for dialogue in dialogues if dialogue.content and len(dialogue.content.strip()) > 0]
            
            if not valid_dialogues:
                logger.info("No valid dialogues to process")
                return results
                
            logger.info(f"Processing {len(valid_dialogues)} dialogues out of {len(dialogues)} total")
            
            self._setup_driver()
            if not self._login():
                raise Exception("Failed to login")
            
            # 获取并打印所有语音及其感情选项
            # voice_emotion_map = self._get_voice_emotion_mappings()
            # if not voice_emotion_map:
            #     logger.error("获取语音感情映射失败，终止处理")
            #     return results
            
            for dialogue in valid_dialogues:
                filepath = self._process_single_dialogue(dialogue)
                if filepath:
                    results[dialogue.id] = filepath
                
        except Exception as e:
            logger.error(f"Error in batch processing: {str(e)}")
        finally:
            if self.driver:
                self.driver.quit()
        
        return results

    def __del__(self):
        """析构函数，确保在对象被销毁时关闭driver"""
        if self.driver:
            try:
                self.driver.quit()
            except:
                pass

    def parse_dialogue_line(self,line: str) -> Optional[DialogueLine]:
        """解析台词文本行"""
        try:
            logger.info(f"开始解析台词行: {line}")
            
            # 解析格式：台词1@男人（孙秀才）@语音a: 云健(成年男)@感情a: embarrassed@强度a: 默认（感情强度）@请问...是阿芝姑娘吗？
            parts = line.split('@')
            if len(parts) != 6:  # 现在应该有6个部分：ID、角色、语音、感情、强度、内容
                logger.error(f"台词行格式错误，应包含6个由@分隔的部分: {line}")
                return None
                
            dialogue_id = parts[0].strip()  # 台词1
            role = parts[1].strip()  # 男人（孙秀才）
            
            try:
                voice = parts[2].split(': ')[1].strip()  # 云健(成年男)
            except IndexError:
                logger.error(f"解析语音选项失败: {parts[2]}")
                return None
                
            try:
                emotion = parts[3].split(': ')[1].strip()  # embarrassed
            except IndexError:
                logger.error(f"解析感情选项失败: {parts[3]}")
                return None
                
            try:
                intensity = parts[4].split(': ')[1].strip()  # 默认（感情强度）
            except IndexError:
                logger.error(f"解析强度选项失败: {parts[4]}")
                return None
                
            content = parts[5].strip()  # 台词内容
            
            logger.info(f"解析结果: ID={dialogue_id}, 角色={role}, 语音={voice}, 感情={emotion}, 强度={intensity}")
            logger.info(f"台词内容: {content}")
            
            return DialogueLine(
                id=dialogue_id,
                role=role,
                voice=voice,
                emotion=emotion,
                intensity=intensity,
                content=content
            )
        except Exception as e:
            logger.error(f"解析台词行时出错: {str(e)}")
            return None

    def test_tts_automation_dialogue(self):
        test_dialogues = [
        ]
        #从一个py文件/mymounnt/xuniji/caijian/taichi.py中读取test_dialogues
        with open("/app/data/dialogues.txt", "r") as f:
            test_dialogues = f.readlines()

        tts = TTSDialogueAutomation()
        parsed_dialogues = []
        for line in test_dialogues:
            dialogue = tts.parse_dialogue_line(line)
            if dialogue:
                parsed_dialogues.append(dialogue)
        
        results = tts.process_dialogues(parsed_dialogues)
        
        for dialogue_id, filepath in results.items():
            print(f"Dialogue {dialogue_id} -> {filepath}") 

if __name__ == "__main__":
    # 测试代码

    test_dialogues = [
"        1@师傅@语音: 云健(成年男)@感情: serious@强度: 1@万老弟，你好像有心事，发财不好吗？",
"2@老者@语音: 云野(老年男)@感情: fearful@强度: 1@发财当然好！有了银子要啥有啥，不想吃不愁喝……",
"3@师傅的女儿@语音: 晓涵(成年女)@感情: affectionate@强度: 1@只是每天提心吊胆，生怕有人算计我的银子……",
"4@师傅@语音: 云健(成年男)@感情: serious@强度: 1@我已经轰走了9个可疑的老婆和84个可疑的佣人，还有7个可疑的儿子我也不放心……",
"5@大徒弟@语音: 云枫(年轻男)@感情: disgruntled@强度: 1@真小气！我们可是都快吃不上饭了！",
"6@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@什么？我还以为能赶上你们的早饭呢！",
"7@师傅@语音: 云健(成年男)@感情: serious@强度: 1@是我给女儿准备的嫁妆，本想悄悄送去，没料到走漏了风声，被贼盯上了……",
"8@大徒弟@语音: 云枫(年轻男)@感情: excited@强度: 1@太妈啦！我又开张了！",
"9@二徒弟@语音: 云夏(儿童男)@感情: fearful@强度: 1@如果你的护送费再便宜点，我请你送……",
"10@师傅@语音: 云健(成年男)@感情: calm@强度: 1@没问题，一切包在我关某身上！",
"11@小孩@语音: 云夏(儿童男)@感情: cheerful@强度: 1@嘿哟！嘿哟！",
"12@强盗@语音: 云野(老年男)@感情: angry@强度: 1@有我这口关王刀在，哪个毛贼敢来！",
"13@师傅@语音: 云健(成年男)@感情: serious@强度: 1@不瞒老弟，关羽是我祖上，我有他亲手画的《关王刀谱》，绝对正宗！",
"14@大徒弟@语音: 云枫(年轻男)@感情: excited@强度: 1@这口刀就是关公过五关斩六将时用的宝刀。",
"15@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@刀上有关公的仙气，天下无敌！",
"16@师傅@语音: 云健(成年男)@感情: serious@强度: 1@你还有什么不放心？",
"17@老者@语音: 云野(老年男)@感情: grateful@强度: 1@放心放心！",
"18@师傅@语音: 云健(成年男)@感情: cheerful@强度: 1@那么运费……",
"19@大徒弟@语音: 云枫(年轻男)@感情: excited@强度: 1@明天早晨我派人把货送过来！",
"20@师傅@语音: 云健(成年男)@感情: cheerful@强度: 1@成交！",
"21@小孩@语音: 云夏(儿童男)@感情: cheerful@强度: 1@哦！",
"22@师傅@语音: 云健(成年男)@感情: excited@强度: 1@快拿酒来！好好庆祝开张大吉！",
"23@大徒弟@语音: 云枫(年轻男)@感情: disgruntled@强度: 1@师父您忘了？咱们早就没钱打酒了！",
"24@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@是吗？没关系！这趟货送到，咱们就有钱了！",
"25@师傅@语音: 云健(成年男)@感情: serious@强度: 1@你们两个，去把刀拿来！",
"26@大徒弟@语音: 云枫(年轻男)@感情: respectful@强度: 1@好的，师父！",
"27@二徒弟@语音: 云夏(儿童男)@感情: respectful@强度: 1@是，师父！",
"28@小孩@语音: 云夏(儿童男)@感情: excited@强度: 1@我也要去！",
"29@师傅的女儿@语音: 晓涵(成年女)@感情: affectionate@强度: 1@爸爸，我也要去！",
"30@老者@语音: 云野(老年男)@感情: concerned@强度: 1@孩子们，小心点啊！",
"31@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@放心吧，爷爷！",
"32@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@我们会小心的！",
"33@小孩@语音: 云夏(儿童男)@感情: innocent@强度: 1@我也会小心的！",
"34@强盗@语音: 云野(老年男)@感情: arrogant@强度: 1@哈哈，今天真是个好日子！",
"35@师傅@语音: 云健(成年男)@感情: anxious@强度: 1@你们两个，快点回来！",
"36@大徒弟@语音: 云枫(年轻男)@感情: urgent@强度: 1@好的，师父！",
"37@二徒弟@语音: 云夏(儿童男)@感情: urgent@强度: 1@是，师父！",
"38@小孩@语音: 云夏(儿童男)@感情: urgent@强度: 1@我也要快点回去！",
"39@师傅的女儿@语音: 晓涵(成年女)@感情: urgent@强度: 1@爸爸，我也要快点回去！",
"40@老者@语音: 云野(老年男)@感情: concerned@强度: 1@孩子们，小心点啊！",
"41@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@放心吧，爷爷！",
"42@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@我们会小心的！",
"43@小孩@语音: 云夏(儿童男)@感情: innocent@强度: 1@我也会小心的！",
"44@强盗@语音: 云野(老年男)@感情: arrogant@强度: 1@哈哈，今天真是个好日子！",
"45@师傅@语音: 云健(成年男)@感情: anxious@强度: 1@你们两个，快点回来！",
"46@大徒弟@语音: 云枫(年轻男)@感情: urgent@强度: 1@好的，师父！",
"47@二徒弟@语音: 云夏(儿童男)@感情: urgent@强度: 1@是，师父！",
"48@小孩@语音: 云夏(儿童男)@感情: urgent@强度: 1@我也要快点回去！",
"49@师傅的女儿@语音: 晓涵(成年女)@感情: urgent@强度: 1@爸爸，我也要快点回去！",
"74@师傅@语音: 云健(成年男)@感情: serious@强度: 1@穿着绿色长袍，头戴斗笠，手持剑。",
"75@师傅的女儿@语音: 晓涵(成年女)@感情: gentle@强度: 1@穿着粉色衣服，头戴花环。",
"76@老者@语音: 云野(老年男)@感情: calm@强度: 1@穿着蓝色长袍，头戴帽子，拄着拐杖。",
"77@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@穿着绿色长袍，头戴斗笠，手持剑。",
"78@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@穿着绿色长袍，头戴斗笠，手持剑。",
"79@小孩@语音: 云夏(儿童男)@感情: fearful@强度: 1@穿着红色衣服，头戴帽子。",
"80@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@穿着黑色衣服，头戴帽子，手持刀。",
"81@师傅@语音: 云健(成年男)@感情: serious@强度: 1@带着他真麻烦！",
"82@师傅的女儿@语音: 晓涵(成年女)@感情: helpless@强度: 1@唉！不过...",
"83@老者@语音: 云野(老年男)@感情: anxious@强度: 1@招得我也想...",
"84@大徒弟@语音: 云枫(年轻男)@感情: disgruntled@强度: 1@大侠也有憋不住的时候...",
"85@二徒弟@语音: 云夏(儿童男)@感情: angry@强度: 1@实在受不了啦！",
"86@小孩@语音: 云夏(儿童男)@感情: fearful@强度: 1@有强盗！",
"87@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@哪里跑！",
"88@师傅@语音: 云健(成年男)@感情: calm@强度: 1@看剑！",
"89@强盗@语音: 云野(老年男)@感情: fearful@强度: 1@妈呀！",
"90@老者@语音: 云野(老年男)@感情: grateful@强度: 1@大王饶命！我知道你们看见我了。第一泡尿我还挺得住，第二泡我可实在受不了啊！",
"91@师傅@语音: 云健(成年男)@感情: confused@强度: 1@你不是强盗？",
"92@老者@语音: 云野(老年男)@感情: explaining@强度: 1@什么？这么说你们也不是？",
"93@大徒弟@语音: 云枫(年轻男)@感情: surprised@强度: 1@白白耗费我的功力！",
"94@二徒弟@语音: 云夏(儿童男)@感情: disgruntled@强度: 1@我是抬轿子的轿夫——轿子刚刚被强盗打劫了。",
"95@小孩@语音: 云夏(儿童男)@感情: excited@强度: 1@我好不容易才逃出来，又被你们给抓了。",
"96@师傅@语音: 云健(成年男)@感情: confident@强度: 1@凭我的武功，我一下子就发现他了！",
"97@师傅的女儿@语音: 晓涵(成年女)@感情: concerned@强度: 1@浑身都湿了，让我怎么见人！",
"98@老者@语音: 云野(老年男)@感情: grateful@强度: 1@幸亏我剑下有准，不然他早没命！",
"99@大徒弟@语音: 云枫(年轻男)@感情: disgruntled@强度: 1@对！我就说去搬救兵，跑了一身汗！",
"100@二徒弟@语音: 云夏(儿童男)@感情: disgruntled@强度: 1@嘿！你们快去救人吧，被强盗抓的人会没命的！",
"101@小孩@语音: 云夏(儿童男)@感情: disgruntled@强度: 1@我们可没时间管闲事！",
"102@师傅@语音: 云健(成年男)@感情: determined@强度: 1@为了那个废物，耽误了这么长时间！",
"103@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@强盗既然抢到人和东西，就不会再回来骚扰我们了。",
"104@师傅@语音: 云健(成年男)@感情: confused@强度: 1@真有强盗？怎么不早说！",
"105@师傅@语音: 云健(成年男)@感情: serious@强度: 1@嘿！回来！去找死呀！",
"106@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@别管闲事！",
"107@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@我去去就来，你们先走吧！",
"108@小孩@语音: 云夏(儿童男)@感情: worried@强度: 1@他跑远了...",
"109@老者@语音: 云野(老年男)@感情: calm@强度: 1@强盗总是在树林深处的。",
"110@师傅的女儿@语音: 晓涵(成年女)@感情: worried@强度: 1@这小子当初来得就不明不白...现在又不明不白地死了，我们怎么向师父交代呀。",
"111@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@站得高，看得远。",
"112@二徒弟@语音: 云夏(儿童男)@感情: disappointed@强度: 1@没找到...",
"113@小孩@语音: 云夏(儿童男)@感情: hopeful@强度: 1@一定会找到的！",
"114@大徒弟@语音: 云枫(年轻男)@感情: calm@强度: 1@去那边看看...",
"115@二徒弟@语音: 云夏(儿童男)@感情: urgent@强度: 1@喂！",
"116@小孩@语音: 云夏(儿童男)@感情: nervous@强度: 1@你看见一个人了吗？",
"117@老者@语音: 云野(老年男)@感情: confused@强度: 1@往那边走了？",
"118@师傅的女儿@语音: 晓涵(成年女)@感情: decisive@强度: 1@知道了！",
"119@大徒弟@语音: 云枫(年轻男)@感情: excited@强度: 1@哈！是从这里走的。",
"120@二徒弟@语音: 云夏(儿童男)@感情: confused@强度: 1@咦？脚印怎么乱了？",
"121@小孩@语音: 云夏(儿童男)@感情: excited@强度: 1@真是要什么有什么，这下我就能找到强盗了。",
"122@大徒弟@语音: 云枫(年轻男)@感情: surprised@强度: 1@呀！",
"123@二徒弟@语音: 云夏(儿童男)@感情: reproachful@强度: 1@是你扔的呀。",
"124@小孩@语音: 云夏(儿童男)@感情: carefree@强度: 1@我正想找个合手的东西呢。",
"125@强盗@语音: 云野(老年男)@感情: nervous@强度: 1@头儿，我们被发现了！",
"126@大徒弟@语音: 云枫(年轻男)@感情: determined@强度: 1@抓住他！别让他跑了！",
"127@二徒弟@语音: 云夏(儿童男)@感情: confident@强度: 1@我是在山上长大的，他还想藏在那儿瞒我！",
"128@小孩@语音: 云夏(儿童男)@感情: scared@强度: 1@啊！有这么多人！",
"129@师傅@语音: 云健(成年男)@感情: serious@强度: 1@语气坚定，对徒弟们进行指导。",
"130@师傅的女儿@语音: 晓涵(成年女)@感情: gentle@强度: 1@语气温柔，关心父亲的安危。",
"131@老者@语音: 云野(老年男)@感情: calm@强度: 1@语气沉稳，似乎在观察周围的动静。",
"132@大徒弟@语音: 云枫(年轻男)@感情: tense@强度: 1@语气紧张，担心师傅的安全。",
"133@二徒弟@语音: 云夏(儿童男)@感情: anxious@强度: 1@语气焦急，希望尽快找到师傅。",
"134@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@语气天真，好奇地看着周围发生的事情。",
"135@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@语气凶狠，威胁要抓走师傅的女儿。",
"136@师傅@语音: 云健(成年男)@感情: serious@强度: 1@孩子们，我们埋伏了半天，就为了抓这个小东西！",
"137@师傅的女儿@语音: 晓涵(成年女)@感情: concerned@强度: 1@爹，你没事吧？",
"138@老者@语音: 云野(老年男)@感情: vigilant@强度: 1@什么？你们想干什么？",
"139@大徒弟@语音: 云枫(年轻男)@感情: tense@强度: 1@师傅，快跑啊！",
"140@二徒弟@语音: 云夏(儿童男)@感情: anxious@强度: 1@师傅，我们来救你了！",
"141@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@哇，他们在干什么呀？",
"142@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@哼，今天你们谁都别想跑！",
"143@师傅@语音: 云健(成年男)@感情: serious@强度: 1@我黑熊大王要是连小孩都制服不了，还算什么山中之王！",
"144@师傅的女儿@语音: 晓涵(成年女)@感情: urgent@强度: 1@胡说！谁是这只癞蛤蟆的未婚妻？",
"145@老者@语音: 云野(老年男)@感情: calm@强度: 1@除了我老婆，还没人敢打我呢！",
"146@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@我也会武功，吓死你们！",
"147@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@放心，漂亮妞没几个有真本事。",
"148@小孩@语音: 云夏(儿童男)@感情: scared@强度: 1@救命呀——杀人啦——",
"149@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@把他杀了不就完了，你的人呢？",
"150@师傅@语音: 云健(成年男)@感情: calm@强度: 1@从此，他就成了山中的大王。",
"151@师傅的女儿@语音: 晓涵(成年女)@感情: curious@强度: 1@还有更好听的吗？我还想听。",
"152@老者@语音: 云野(老年男)@感情: surprised@强度: 1@你真行，还会做衣服。",
"153@大徒弟@语音: 云枫(年轻男)@感情: tense@强度: 1@你以为我们在为你讲故事吗！",
"154@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@你以为我会怕你吗！",
"155@小孩@语音: 云夏(儿童男)@感情: scared@强度: 1@大王，别放过这小子！",
"156@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@嘿！看谁以后还敢给我捣乱！",
"157@师傅@语音: 云健(成年男)@感情: serious@强度: 1@别过来！再往前走我动武了！",
"158@师傅的女儿@语音: 晓涵(成年女)@感情: worried@强度: 1@找到啦！轿子！",
"159@老者@语音: 云野(老年男)@感情: confused@强度: 1@咦？轿子里的人呢？",
"160@大徒弟@语音: 云枫(年轻男)@感情: surprised@强度: 1@哈！你就是轿子里的人吧？",
"161@师傅的女儿@语音: 晓涵(成年女)@感情: anxious@强度: 1@你是来救我的吗？你为什么不早来！刚才那帮家伙差点害了我。",
"162@老者@语音: 云野(老年男)@感情: reproachful@强度: 1@再说，你会打架不来救人你还有什么用！",
"163@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@念你是初犯就算了，以后记住教训。",
"164@大徒弟@语音: 云枫(年轻男)@感情: urgent@强度: 1@还等什么？快抬轿子！",
"165@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@可是...只有我一个人怎么抬？",
"166@师傅的女儿@语音: 晓涵(成年女)@感情: reproachful@强度: 1@你不是人吗！既然救人就救到底，你来抬轿子。",
"167@二徒弟@语音: 云夏(儿童男)@感情: confused@强度: 1@她怎么这样？",
"168@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@你还小，不懂，女孩漂亮就这样。",
"169@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@除非遇到比她凶的人...",
"170@师傅的女儿@语音: 晓涵(成年女)@感情: angry@强度: 1@我可不喜欢被人指着鼻子！",
"171@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@嘿！快出来自己走！",
"172@二徒弟@语音: 云夏(儿童男)@感情: reproachful@强度: 1@我只是随便一说，你别真...",
"173@强盗@语音: 云野(老年男)@感情: pleading@强度: 1@救命呀！别打啦！",
"174@师傅的女儿@语音: 晓涵(成年女)@感情: scared@强度: 1@我听话就是了，别打我...",
"175@强盗@语音: 云野(老年男)@感情: confident@强度: 1@这招真灵！嘿嘿！",
"176@师傅的女儿@语音: 晓涵(成年女)@感情: angry@强度: 1@哼！我早就知道男人没好东西！",
"177@强盗@语音: 云野(老年男)@感情: arrogant@强度: 1@像我这样的美女，到处有人抢...",
"178@师傅的女儿@语音: 晓涵(成年女)@感情: defiant@强度: 1@我才不和你们一般见识！别觉得你们有多么了不起！",
"179@小孩@语音: 云夏(儿童男)@感情: brave@强度: 1@我什么都不怕！",
"180@师傅的女儿@语音: 晓涵(成年女)@感情: scared@强度: 1@妈呀！",
"181@师傅的女儿@语音: 晓涵(成年女)@感情: confused@强度: 1@这个很可怕吗？",
"182@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@快弄走它！",
"183@师傅的女儿@语音: 晓涵(成年女)@感情: scared@强度: 1@吓死我了！",
"184@小孩@语音: 云夏(儿童男)@感情: brave@强度: 1@除了虫子我什么都不怕！",
"185@师傅的女儿@语音: 晓涵(成年女)@感情: confused@强度: 1@你怎么了？",
"186@小孩@语音: 云夏(儿童男)@感情: confused@强度: 1@我还从来没...",
"187@师傅的女儿@语音: 晓涵(成年女)@感情: reproachful@强度: 1@你瞎了吗？",
"188@小孩@语音: 云夏(儿童男)@感情: scared@强度: 1@妈呀！",
"189@师傅@语音: 云健(成年男)@感情: serious@强度: 1@老糊涂！虫子有什么可怕的？",
"190@师傅的女儿@语音: 晓涵(成年女)@感情: angry@强度: 1@你别以为我黑熊大王就好对付！",
"191@老者@语音: 云野(老年男)@感情: serious@强度: 1@嘿哟！我要把你剁成肉酱！",
"192@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@刚才我一掌把他弄到这儿了，这下我有的打了。",
"193@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@又没砍到！真砍上就没命了！",
"194@小孩@语音: 云夏(儿童男)@感情: scared@强度: 1@现在该你躲我了！",
"195@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@这小子手真重……这么不禁打？我去找棵树……就这棵。",
"196@师傅@语音: 云健(成年男)@感情: serious@强度: 1@他是一位武术高手，正在教导他的徒弟们。",
"197@师傅的女儿@语音: 晓涵(成年女)@感情: indifferent@强度: 1@她是一个年轻女孩，似乎对武术不太感兴趣。",
"198@老者@语音: 云野(老年男)@感情: calm@强度: 1@他是一位年长的智者，似乎在观察或指导这场武术训练。",
"199@大徒弟@语音: 云枫(年轻男)@感情: excited@强度: 1@他是师傅的大徒弟，正在展示他的武术技巧。",
"200@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@他是师傅的二徒弟，也在参与武术训练。",
"201@小孩@语音: 云夏(儿童男)@感情: excited@强度: 1@他是一个小男孩，似乎对武术很感兴趣。",
"202@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@他试图抢走师傅女儿的财物。",
"203@师傅@语音: 云健(成年男)@感情: serious@强度: 1@你从哪儿找来这么漂亮的...",
"204@师傅的女儿@语音: 晓涵(成年女)@感情: curious@强度: 1@我说你怎么会去，原来你知道有她。",
"205@老者@语音: 云野(老年男)@感情: surprised@强度: 1@我倒是要知道还有你的份！",
"206@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@小姐请上车，我一直在这儿等你呢。",
"207@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@要不要我扶你上车？",
"208@小孩@语音: 云夏(儿童男)@感情: excited@强度: 1@滚下来！让小姐先上！",
"209@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@你们俩自己走吧，车上坐不下。",
"210@师傅@语音: 云健(成年男)@感情: serious@强度: 1@驾！快走！",
"211@师傅的女儿@语音: 晓涵(成年女)@感情: angry@强度: 1@臭马，再不走我杀了你做红烧肉！",
"212@老者@语音: 云野(老年男)@感情: calm@强度: 1@有机会让你见识我的武功...",
"213@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@刚才才是我派郎偷救你的。",
"214@师傅@语音: 云健(成年男)@感情: serious@强度: 1@他的武功还是我教的呢。",
"215@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@为了练武，我到现在还没成亲...",
"216@老者@语音: 云野(老年男)@感情: serious@强度: 1@像我这样的名人，一般的女孩我看不上。",
"217@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@咱们在这儿吃点东西。",
"218@师傅@语音: 云健(成年男)@感情: serious@强度: 1@啊——客官里面请——",
"219@大徒弟@语音: 云枫(年轻男)@感情: confused@强度: 1@他为什么叫我们'客'官？",
"220@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@大家都想当官，听到别人叫'官'就高兴。",
"221@小孩@语音: 云夏(儿童男)@感情: cheerful@强度: 1@客官，想吃什么尽管说？",
"222@师傅@语音: 云健(成年男)@感情: serious@强度: 1@都有什么好吃的？",
"223@师傅的女儿@语音: 晓涵(成年女)@感情: cheerful@强度: 1@只有烧牛肉。",
"224@老者@语音: 云野(老年男)@感情: calm@强度: 1@那就牛肉吧，还有酒和馒头。",
"225@小孩@语音: 云夏(儿童男)@感情: cheerful@强度: 1@哈！客官点的菜我们都有，我的菜最齐！",
"226@师傅@语音: 云健(成年男)@感情: serious@强度: 1@马三儿，上菜！",
"227@大徒弟@语音: 云枫(年轻男)@感情: disgruntled@强度: 1@干这么多年，只赚这一种菜，您透了！",
"228@二徒弟@语音: 云夏(儿童男)@感情: cheerful@强度: 1@客官再尝尝我们的名菜。",
"229@小孩@语音: 云夏(儿童男)@感情: cheerful@强度: 1@又是那套老词，早听烦了！",
"230@师傅@语音: 云健(成年男)@感情: serious@强度: 1@五年前知县大人路过这里，喝了我们的酒说：不坏！",
"231@师傅的女儿@语音: 晓涵(成年女)@感情: curious@强度: 1@瞧！那就是知县大人用过的碗。",
"232@师傅@语音: 云健(成年男)@感情: serious@强度: 1@昨天我们喝了他家的酒就人事不知，马车才丢的！",
"233@老者@语音: 云野(老年男)@感情: confused@强度: 1@哦？",
"234@师傅的女儿@语音: 晓涵(成年女)@感情: angry@强度: 1@快说！你在你的破酒里放了什么？不说我就一刀劈了你！",
"235@大徒弟@语音: 云枫(年轻男)@感情: surprised@强度: 1@什么？",
"236@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@你敢说我的酒是破酒，那是知县大人说过不坏的名酒！",
"237@小孩@语音: 云夏(儿童男)@感情: angry@强度: 1@我开了这么多年酒店，还没人敢当面说我的酒不好呢！气死我了。",
"238@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@既然你们怀疑我的名酒，我就当面喝给你们看！",
"239@师傅@语音: 云健(成年男)@感情: serious@强度: 1@我喝完了！",
"240@老者@语音: 云野(老年男)@感情: confused@强度: 1@我怎么就没事？",
"241@小孩@语音: 云夏(儿童男)@感情: carefree@强度: 1@我不过是随便说说的，嘿嘿...",
"242@强盗@语音: 云野(老年男)@感情: confident@强度: 1@哈！我说什么来着！",
"243@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@一定是那个伙计马三儿搞的鬼！",
"244@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@看他能藏到哪儿！",
"245@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@哪儿都没有！",
"246@小孩@语音: 云夏(儿童男)@感情: serious@强度: 1@看来是跑了...",
"247@强盗@语音: 云野(老年男)@感情: serious@强度: 1@切肉刀，太好啦！",
"248@师傅@语音: 云健(成年男)@感情: serious@强度: 1@救命！",
"249@老者@语音: 云野(老年男)@感情: serious@强度: 1@快说！我们的马车在哪儿？",
"250@小孩@语音: 云夏(儿童男)@感情: serious@强度: 1@我说我说！我全说！",
"251@强盗@语音: 云野(老年男)@感情: serious@强度: 1@是黑熊山的二大王让我下的麻药，他给我二百两银子...",
"252@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@我想快点儿发财...",
"253@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@我当伙计早当烦了！",
"254@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@把他们安顿好，我们快走！",
"255@小孩@语音: 云夏(儿童男)@感情: serious@强度: 1@马三儿，别忘了收那几个人的店钱！",
"256@强盗@语音: 云野(老年男)@感情: serious@强度: 1@真不愧是知县大人说不坏的名酒，酒力真大！",
"257@师傅@语音: 云健(成年男)@感情: serious@强度: 1@快追！",
"258@师傅的女儿@语音: 晓涵(成年女)@感情: anxious@强度: 1@（没有直接对话，但通过表情和动作表现出焦急）",
"259@老者@语音: 云野(老年男)@感情: tired@强度: 1@（没有直接对话，但通过表情和动作表现出疲惫）",
"260@大徒弟@语音: 云枫(年轻男)@感情: tense@强度: 1@（没有直接对话，但通过表情和动作表现出紧张）",
"261@二徒弟@语音: 云夏(儿童男)@感情: tense@强度: 1@（没有直接对话，但通过表情和动作表现出紧张）",
"262@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@（没有直接对话，但通过表情和动作表现出好奇）",
"263@强盗@语音: 云野(老年男)@感情: serious@强度: 1@也难怪，这匹马比我爷爷都老，还没睡醒呢。",
"264@强盗@语音: 云野(老年男)@感情: serious@强度: 1@什么？凭什么让我们抬！他们为什么不抬？",
"265@强盗@语音: 云野(老年男)@感情: serious@强度: 1@天呐！一定是他们有防备，把东西拿出去了。",
"266@强盗@语音: 云野(老年男)@感情: serious@强度: 1@咱们还是开豆腐坊吧。",
"267@师傅@语音: 云健(成年男)@感情: serious@强度: 1@就让他呆在里面吧。",
"268@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@我对马三儿这么好，他不可能背叛我！",
"269@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@你们只需交银子！我可不愿冤枉我的伙计！",
"270@老者@语音: 云野(老年男)@感情: angry@强度: 1@……还想诬赖我的伙计！",
"271@师傅的女儿@语音: 晓涵(成年女)@感情: concerned@强度: 1@马三儿，委屈你了。",
"272@马三儿@语音: 云夏(儿童男)@感情: serious@强度: 1@都是他们想害你，我知道你不是坏人。",
"273@大徒弟@语音: 云枫(年轻男)@感情: serious@强度: 1@我可不心软，我要当老板！",
"274@二徒弟@语音: 云夏(儿童男)@感情: urgent@强度: 1@放我出去！",
"275@老者@语音: 云野(老年男)@感情: surprised@强度: 1@果然是空的！",
"276@大徒弟@语音: 云枫(年轻男)@感情: desperate@强度: 1@全完了！",
"277@二徒弟@语音: 云夏(儿童男)@感情: helpless@强度: 1@东西早被强盗拿走了！",
"278@师傅@语音: 云健(成年男)@感情: depressed@强度: 1@江湖上武林中人都会笑话我刘贵的…",
"279@大徒弟@语音: 云枫(年轻男)@感情: regretful@强度: 1@我刘贵再也没脸干保镖这行了…",
"280@二徒弟@语音: 云夏(儿童男)@感情: hopeless@强度: 1@我的前途全毁了！",
"281@师傅的女儿@语音: 晓涵(成年女)@感情: determined@强度: 1@回家我就向师父辞职！",
"282@师傅@语音: 云健(成年男)@感情: comforting@强度: 1@师兄别开些，这也不全是你的错…",
"283@大徒弟@语音: 云枫(年轻男)@感情: encouraging@强度: 1@你确实是英雄…别这样…",
"284@二徒弟@语音: 云夏(儿童男)@感情: calm@强度: 1@还是先到目的地再说吧。",
"285@小孩@语音: 云夏(儿童男)@感情: casual@强度: 1@想吃什么就吃什么吧…",
"286@师傅的女儿@语音: 晓涵(成年女)@感情: determined@强度: 1@可是，我不能让强盗笑话我！",
"287@大徒弟@语音: 云枫(年轻男)@感情: decisive@强度: 1@我多找些石头放在箱子里。",
"288@二徒弟@语音: 云夏(儿童男)@感情: cautious@强度: 1@这样就不会有人知道我们丢了镖。",
"289@师傅的女儿@语音: 晓涵(成年女)@感情: cautious@强度: 1@我们要作出保住镖的样子，别让人怀疑…",
"290@师傅@语音: 云健(成年男)@感情: confused@强度: 1@走了三天，还是没强盗劫咱们，难道他们都知道了？",
"291@大徒弟@语音: 云枫(年轻男)@感情: regretful@强度: 1@这下我的面子可丢尽了！",
"292@二徒弟@语音: 云夏(儿童男)@感情: relaxed@强度: 1@到地方了！",
"293@师傅的女儿@语音: 晓涵(成年女)@感情: serious@强度: 1@这上写着是在镇子的东头…",
"294@大徒弟@语音: 云枫(年轻男)@感情: confident@强度: 1@就是这儿！",
"295@二徒弟@语音: 云夏(儿童男)@感情: surprised@强度: 1@万百金！他倒先来了。",
"296@师傅的女儿@语音: 晓涵(成年女)@感情: surprised@强度: 1@看来他知道了一切！",
"297@师傅@语音: 云健(成年男)@感情: calm@强度: 1@万老板，钱是身外之物，不必太放在心上...",
"298@老者@语音: 云野(老年男)@感情: anxious@强度: 1@你懂什么！要真是钱丢了，那可要我的老命了！",
"299@师傅的女儿@语音: 晓涵(成年女)@感情: urgent@强度: 1@是我女儿丢了！",
"300@大徒弟@语音: 云枫(年轻男)@感情: lighthearted@强度: 1@这两箱金子就是给她的嫁妆！",
"301@二徒弟@语音: 云夏(儿童男)@感情: serious@强度: 1@在这个世上除了金子，我最疼我女儿了！",
"302@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@你说谁？",
"303@强盗@语音: 云野(老年男)@感情: threatening@强度: 1@有人放暗箭！",
"304@师傅@语音: 云健(成年男)@感情: serious@强度: 1@快追！",
"305@师傅的女儿@语音: 晓涵(成年女)@感情: anxious@强度: 1@（没有直接对话，但通过表情和动作表现出焦急）",
"306@老者@语音: 云野(老年男)@感情: tired@强度: 1@（没有直接对话，但通过表情和动作表现出疲惫）",
"307@大徒弟@语音: 云枫(年轻男)@感情: tense@强度: 1@（没有直接对话，但通过表情和动作表现出紧张）",
"308@二徒弟@语音: 云夏(儿童男)@感情: tense@强度: 1@（没有直接对话，但通过表情和动作表现出紧张）",
"309@小孩@语音: 云夏(儿童男)@感情: curious@强度: 1@（没有直接对话，但通过表情和动作表现出好奇）",
"310@强盗@语音: 云野(老年男)@感情: serious@强度: 1@也难怪，这匹马比我爷爷都老，还没睡醒呢。",
"311@强盗@语音: 云野(老年男)@感情: serious@强度: 1@什么？凭什么让我们抬！他们为什么不抬？",
"312@强盗@语音: 云野(老年男)@感情: serious@强度: 1@天呐！一定是他们有防备，把东西拿出去了。",
"313@强盗@语音: 云野(老年男)@感情: serious@强度: 1@咱们还是开豆腐坊吧."

]
    
    tts = TTSDialogueAutomation()
    parsed_dialogues = []
    for line in test_dialogues:
        dialogue = tts.parse_dialogue_line(line)
        if dialogue:
            parsed_dialogues.append(dialogue)
    
    results = tts.process_dialogues(parsed_dialogues)
    
    for dialogue_id, filepath in results.items():
        print(f"Dialogue {dialogue_id} -> {filepath}") 